package com.plpm.util;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 文件哈希值计算工具类
 * 使用SHA-256算法计算文件的哈希值
 *
 * @author PLPM Team
 * @version 1.0
 */
public class FileHashUtil {

    /**
     * 计算文件的SHA-256哈希值
     *
     * @param filePath 文件路径
     * @return SHA-256哈希值（64位十六进制字符串）
     * @throws IOException 文件读取异常
     * @throws NoSuchAlgorithmException 算法不支持异常
     */
    public static String calculateSHA256(String filePath) throws IOException, NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        try (FileInputStream fis = new FileInputStream(filePath)) {
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                md.update(buffer, 0, bytesRead);
            }
        }
        byte[] digest = md.digest();
        return bytesToHex(digest);
    }

    /**
     * 计算输入流的SHA-256哈希值
     *
     * @param inputStream 输入流
     * @return SHA-256哈希值（64位十六进制字符串）
     * @throws IOException 流读取异常
     * @throws NoSuchAlgorithmException 算法不支持异常
     */
    public static String calculateSHA256(InputStream inputStream) throws IOException, NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            md.update(buffer, 0, bytesRead);
        }
        byte[] digest = md.digest();
        return bytesToHex(digest);
    }

    /**
     * 计算字节数组的SHA-256哈希值
     *
     * @param data 字节数组
     * @return SHA-256哈希值（64位十六进制字符串）
     * @throws NoSuchAlgorithmException 算法不支持异常
     */
    public static String calculateSHA256(byte[] data) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] digest = md.digest(data);
        return bytesToHex(digest);
    }

    /**
     * 将字节数组转换为十六进制字符串
     *
     * @param bytes 字节数组
     * @return 十六进制字符串
     */
    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }

    /**
     * 验证文件的SHA-256哈希值
     *
     * @param filePath 文件路径
     * @param expectedHash 期望的哈希值
     * @return 是否匹配
     * @throws IOException 文件读取异常
     * @throws NoSuchAlgorithmException 算法不支持异常
     */
    public static boolean verifySHA256(String filePath, String expectedHash) throws IOException, NoSuchAlgorithmException {
        String actualHash = calculateSHA256(filePath);
        return actualHash.equalsIgnoreCase(expectedHash);
    }

    /**
     * 验证输入流的SHA-256哈希值
     *
     * @param inputStream 输入流
     * @param expectedHash 期望的哈希值
     * @return 是否匹配
     * @throws IOException 流读取异常
     * @throws NoSuchAlgorithmException 算法不支持异常
     */
    public static boolean verifySHA256(InputStream inputStream, String expectedHash) throws IOException, NoSuchAlgorithmException {
        String actualHash = calculateSHA256(inputStream);
        return actualHash.equalsIgnoreCase(expectedHash);
    }
}
